﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine;

/// <summary>
/// 全局事件
/// </summary>
public class GloblEvent
{
    public delegate void EventHandle(params object[] objs);

    //public delegate void EventHandle<T>(T t, params object[] arrgs);
    #region Enum标志位事件字典
    //可重复添加相同事件
    private static Dictionary<Enum,EventHandle> m_EventDic=new Dictionary<Enum, EventHandle>();
    //只触发一次，自动回收
    private static Dictionary<Enum,List<EventHandle>> m_UseOnceEventDic=new Dictionary<Enum, List<EventHandle>>();
    /// <summary>
    /// 添加事件（false为不可重复）
    /// </summary>
    /// <param name="type">键</param>
    /// <param name="handle">事件</param>
    /// <param name="isUseOnce">添加到可重复/不可重复事件字典中</param>
    public static void AddEvent(Enum type, EventHandle handle, bool isUseOnce = false)
    {
        if (isUseOnce)
        {
            if (m_UseOnceEventDic.ContainsKey(type))
            {
                if (!m_UseOnceEventDic[type].Contains(handle))
                {
                    m_UseOnceEventDic[type].Add(handle);
                }
                else
                {
                    Debug.LogError("禁止重复添加");
                }
            }
            else
            {
                List<EventHandle> go=new List<EventHandle>();
                go.Add(handle);
                m_UseOnceEventDic.Add(type,go);
            }
        }
        else
        {
            if (m_EventDic.ContainsKey(type))
            {
                m_EventDic[type] += handle;
            }
            else
            {
                m_EventDic.Add(type,handle);
            }
        }
    }

    public static void RemoveEvent(Enum type, EventHandle handle)
    {
        if (m_UseOnceEventDic.ContainsKey(type))
        {
            if (m_UseOnceEventDic[type].Contains(handle))
            {
                m_UseOnceEventDic[type].Remove(handle);
                if (m_UseOnceEventDic[type].Count.Equals(0))
                {
                    m_UseOnceEventDic.Remove(type);
                }
            }
        }

        if (m_EventDic.ContainsKey(type))
        {
            m_EventDic[type] -= handle;
        }
    }

    public static void RemoveEvent(Enum type)
    {
        if (m_UseOnceEventDic.ContainsKey(type))
        {
            m_UseOnceEventDic.Remove(type);
        }

        if (m_EventDic.ContainsKey(type))
        {
            m_EventDic.Remove(type);
        }
    }
    //派发事件标志位
    private static int Dis = 0;
    public static void DisoatchEvent(Enum type, params object[] args)
    {
        Dis = 0;
        if (m_EventDic.ContainsKey(type))
        {
            try
            {
                if (m_EventDic[type]!=null)
                {
                    m_EventDic[type](args);
                    Dis = 1;
                }
            }
            catch (Exception e)
            {
               Debug.LogError(e.ToString());
            }
        }

        if (m_UseOnceEventDic.ContainsKey(type))
        {
            for (int i = 0,j=m_UseOnceEventDic[type].Count; i < j; i++)
            {
                try
                {
                    m_UseOnceEventDic[type][i](args);
                    Dis = 1;
                }
                catch (Exception e)
                {
                    Debug.LogError(e.ToString());
                }
            }
            RemoveEvent(type);
        }

        if (!Dis.Equals(1))
        {
            Debug.LogError("派发事件失败，事件类型:"+type+"可能为空，没有添加事件");
        }
    }
    #endregion
    #region String标志位事件字典
    //可重复添加相同事件
    private static Dictionary<string, EventHandle> m_stringEventDic = new Dictionary<string, EventHandle>();
    //只触发一次，自动回收
    private static Dictionary<string, List<EventHandle>> m_stringUseOnceEventDic = new Dictionary<string, List<EventHandle>>();
    /// <summary>
    /// 添加事件（false为不可重复）
    /// </summary>
    /// <param name="type">键</param>
    /// <param name="handle">事件</param>
    /// <param name="isUseOnce">添加到可重复/不可重复事件字典中</param>
    public static void AddEvent(string type, EventHandle handle, bool isUseOnce = false)
    {
        if (isUseOnce)
        {
            if (m_stringUseOnceEventDic.ContainsKey(type))
            {
                if (!m_stringUseOnceEventDic[type].Contains(handle))
                {
                    m_stringUseOnceEventDic[type].Add(handle);
                }
                else
                {
                    Debug.LogError("禁止重复添加");
                }
            }
            else
            {
                List<EventHandle> go = new List<EventHandle>();
                go.Add(handle);
                m_stringUseOnceEventDic.Add(type, go);
            }
        }
        else
        {
            if (m_stringEventDic.ContainsKey(type))
            {
                m_stringEventDic[type] += handle;
            }
            else
            {
                m_stringEventDic.Add(type, handle);
            }
        }
    }

    public static void RemoveEvent(string type, EventHandle handle)
    {
        if (m_stringUseOnceEventDic.ContainsKey(type))
        {
            if (m_stringUseOnceEventDic[type].Contains(handle))
            {
                m_stringUseOnceEventDic[type].Remove(handle);
                if (m_stringUseOnceEventDic[type].Count.Equals(0))
                {
                    m_stringUseOnceEventDic.Remove(type);
                }
            }
        }

        if (m_stringEventDic.ContainsKey(type))
        {
            m_stringEventDic[type] -= handle;
        }
    }

    public static void RemoveEvent(string type)
    {
        if (m_stringUseOnceEventDic.ContainsKey(type))
        {
            m_stringUseOnceEventDic.Remove(type);
        }

        if (m_stringEventDic.ContainsKey(type))
        {
            m_stringEventDic.Remove(type);
        }
    }
    //派发事件标志位
    private static int stringDis = 0;
    public static void DisoatchEvent(string type, params object[] args)
    {
        stringDis = 0;
        if (m_stringEventDic.ContainsKey(type))
        {
            try
            {
                if (m_stringEventDic[type] != null)
                {
                    m_stringEventDic[type](args);
                    stringDis = 1;
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e.ToString());
            }
        }

        if (m_stringUseOnceEventDic.ContainsKey(type))
        {
            for (int i = 0, j = m_stringUseOnceEventDic[type].Count; i < j; i++)
            {
                try
                {
                    m_stringUseOnceEventDic[type][i](args);
                    stringDis = 1;
                }
                catch (Exception e)
                {
                    Debug.LogError(e.ToString());
                }
            }
            RemoveEvent(type);
        }

        if (!stringDis.Equals(1))
        {
            Debug.LogError("派发事件失败，事件类型:" + type + "可能为空，没有添加事件");
        }
    }
    #endregion
    #region INT标志位事件字典
    //可重复添加相同事件
    private static Dictionary<int, EventHandle> m_INTEventDic = new Dictionary<int, EventHandle>();
    //只触发一次，自动回收
    private static Dictionary<int, List<EventHandle>> m_INTUseOnceEventDic = new Dictionary<int, List<EventHandle>>();
    /// <summary>
    /// 添加事件（false为不可重复）
    /// </summary>
    /// <param name="type">键</param>
    /// <param name="handle">事件</param>
    /// <param name="isUseOnce">添加到可重复/不可重复事件字典中</param>
    public static void AddEvent(int type, EventHandle handle, bool isUseOnce = false)
    {
        if (isUseOnce)
        {
            if (m_INTUseOnceEventDic.ContainsKey(type))
            {
                if (!m_INTUseOnceEventDic[type].Contains(handle))
                {
                    m_INTUseOnceEventDic[type].Add(handle);
                }
                else
                {
                    Debug.LogError("禁止重复添加");
                }
            }
            else
            {
                List<EventHandle> go = new List<EventHandle>();
                go.Add(handle);
                m_INTUseOnceEventDic.Add(type, go);
            }
        }
        else
        {
            if (m_INTEventDic.ContainsKey(type))
            {
                m_INTEventDic[type] += handle;
            }
            else
            {
                m_INTEventDic.Add(type, handle);
            }
        }
    }

    public static void RemoveEvent(int type, EventHandle handle)
    {
        if (m_INTUseOnceEventDic.ContainsKey(type))
        {
            if (m_INTUseOnceEventDic[type].Contains(handle))
            {
                m_INTUseOnceEventDic[type].Remove(handle);
                if (m_INTUseOnceEventDic[type].Count.Equals(0))
                {
                    m_INTUseOnceEventDic.Remove(type);
                }
            }
        }

        if (m_INTEventDic.ContainsKey(type))
        {
            m_INTEventDic[type] -= handle;
        }
    }

    public static void RemoveEvent(int type)
    {
        if (m_INTUseOnceEventDic.ContainsKey(type))
        {
            m_INTUseOnceEventDic.Remove(type);
        }

        if (m_INTEventDic.ContainsKey(type))
        {
            m_INTEventDic.Remove(type);
        }
    }
    //派发事件标志位
    private static int INTDis = 0;
    public static void DisoatchEvent(int type, params object[] args)
    {
        INTDis = 0;
        if (m_INTEventDic.ContainsKey(type))
        {
            try
            {
                if (m_INTEventDic[type] != null)
                {
                    m_INTEventDic[type](args);
                    INTDis = 1;
                }
            }
            catch (Exception e)
            {
                Debug.LogError(e.ToString());
            }
        }

        if (m_INTUseOnceEventDic.ContainsKey(type))
        {
            for (int i = 0, j = m_INTUseOnceEventDic[type].Count; i < j; i++)
            {
                try
                {
                    m_INTUseOnceEventDic[type][i](args);
                    INTDis = 1;
                }
                catch (Exception e)
                {
                    Debug.LogError(e.ToString());
                }
            }
            RemoveEvent(type);
        }

        if (!INTDis.Equals(1))
        {
            Debug.LogError("派发事件失败，事件类型:" + type + "可能为空，没有添加事件");
        }
    }
    #endregion
}

